home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP12.ZIP / PATRON / IUILINK.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-19  |  12.6 KB  |  513 lines

  1. /*
  2.  * IUILINK.CPP
  3.  *
  4.  * Implementation of an object with the IOleUILinkContainer interface
  5.  * necessary to use the Links Dialog in OLE2UI.  This is implemented as
  6.  * a stand-along object with access to the CPage with which its associated,
  7.  * primiarily because it is only used for the one dialog.  Therefore this
  8.  * object has it's own IUnknown.  In addition, we use the Links Assistant
  9.  * object developed in this chapter to simplify our own code.
  10.  *
  11.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  12.  *
  13.  * Kraig Brockschmidt, Software Design Engineer
  14.  * Microsoft Systems Developer Relations
  15.  *
  16.  * Internet  :  kraigb@microsoft.com
  17.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  18.  */
  19.  
  20.  
  21. #include "patron.h"
  22.  
  23.  
  24. /*
  25.  * CIOleUILinkContainer::CIOleUILinkContainer
  26.  * CIOleUILinkContainer::~CIOleUILinkContainer
  27.  *
  28.  * Parameters (Constructor):
  29.  *  pPage           LPPAGE of the page we're in.
  30.  */
  31.  
  32. CIOleUILinkContainer::CIOleUILinkContainer(LPPAGE pPage)
  33.     {
  34.     m_cRef=0;
  35.     m_pPage=pPage;
  36.     m_iTenant=0;
  37.     m_pDelIUILinks=NULL;
  38.     m_fDirty=FALSE;
  39.     return;
  40.     }
  41.  
  42. CIOleUILinkContainer::~CIOleUILinkContainer(void)
  43.     {
  44.     if (NULL!=m_pDelIUILinks)
  45.         m_pDelIUILinks->Release();
  46.  
  47.     return;
  48.     }
  49.  
  50.  
  51.  
  52. /*
  53.  * CIOleUILinkContainre::FInit
  54.  *
  55.  * Purpose:
  56.  *  Performs initialization on the object that might fail.  In particular
  57.  *  this creates an object of CLSID_LinksAssistant that helps in
  58.  *  implementing this interface.
  59.  *
  60.  * Parameters:
  61.  *  None
  62.  *
  63.  * Return Value:
  64.  *  BOOL            TRUE if successful, FALSE otherwise.
  65.  */
  66.  
  67. BOOL CIOleUILinkContainer::FInit(void)
  68.     {
  69.     HRESULT     hr;
  70.  
  71.     hr=CoCreateInstance(CLSID_LinksAssistant, NULL, CLSCTX_INPROC_SERVER
  72.         , IID_IOleUILinkContainer, (LPLPVOID)&m_pDelIUILinks);
  73.  
  74.     return SUCCEEDED(hr);
  75.     }
  76.  
  77.  
  78.  
  79.  
  80.  
  81. /*
  82.  * CIOleUILinkContainer::QueryInterface
  83.  * CIOleUILinkContainer::AddRef
  84.  * CIOleUILinkContainer::Release
  85.  *
  86.  * Purpose:
  87.  *  IUnknown members for CIOleUILinkContainer object.
  88.  */
  89.  
  90. STDMETHODIMP CIOleUILinkContainer::QueryInterface(REFIID riid, LPLPVOID ppv)
  91.     {
  92.     *ppv=NULL;
  93.  
  94.     if (IsEqualIID(riid, IID_IUnknown)
  95.         || IsEqualIID(riid, IID_IOleUILinkContainer))
  96.         {
  97.         *ppv=(LPVOID)this;
  98.         AddRef();
  99.         return NOERROR;
  100.         }
  101.  
  102.     return ResultFromScode(E_NOINTERFACE);
  103.     }
  104.  
  105.  
  106. STDMETHODIMP_(ULONG) CIOleUILinkContainer::AddRef(void)
  107.     {
  108.     return ++m_cRef;
  109.     }
  110.  
  111. STDMETHODIMP_(ULONG) CIOleUILinkContainer::Release(void)
  112.     {
  113.     ULONG           cRefT;
  114.  
  115.     cRefT=--m_cRef;
  116.  
  117.     if (0L==m_cRef)
  118.         delete this;
  119.  
  120.     return cRefT;
  121.     }
  122.  
  123.  
  124.  
  125. /*
  126.  * CIOleUILinkContainer::GetNextLink
  127.  *
  128.  * Purpose:
  129.  *  Called when the Links dialog is filling its listbox.  Here we
  130.  *  need to return a key for the first link if dwLink is zero, then
  131.  *  return the next links if it's non-zero.
  132.  *
  133.  * Parameters:
  134.  *  dwLink          DWORD last returned from this function.  Zero if
  135.  *                  this is the first call to this function.
  136.  *
  137.  * Return Value:
  138.  *  DWORD           Some value that identifies this object.  Zero stops
  139.  *                  the sequence such that this function is no longer called.
  140.  */
  141.  
  142. STDMETHODIMP_(DWORD) CIOleUILinkContainer::GetNextLink(DWORD dwLink)
  143.     {
  144.     LPTENANT        pTenant;
  145.  
  146.     //If we're told to start the sequence, set index to zero.
  147.     if (0==dwLink)
  148.         m_iTenant=0;
  149.  
  150.     /*
  151.      * On each subsequent call, find the next linked object in
  152.      * this document and return it.  Make sure the index is incremented
  153.      * for the next time this function is called.
  154.      */
  155.     for ( ; m_iTenant < m_pPage->m_cTenants; m_iTenant++)
  156.         {
  157.         if (m_pPage->FTenantGet(m_iTenant, &pTenant, FALSE))
  158.             {
  159.             if (TENANTTYPE_LINKEDOBJECT==pTenant->TypeGet())
  160.                 {
  161.                 m_iTenant++;
  162.                 return (DWORD)pTenant;
  163.                 }
  164.             }
  165.         }
  166.  
  167.     //If we hit the end of list, this tells the dialog to stop.
  168.     return 0L;
  169.     }
  170.  
  171.  
  172.  
  173.  
  174.  
  175. /*
  176.  * CIOleUILinkContainer::SetLinkUpdateOptions
  177.  *
  178.  * Purpose:
  179.  *  Informs the application to call IOleLink::SetUpdateOptions for
  180.  *  the object identified by dwLink.
  181.  *
  182.  * Parameters:
  183.  *  dwLink          DWORD object identifier as returned from GetNextLink.
  184.  *  dwOptions       DWORD containing the new options.
  185.  *
  186.  * Return Value:
  187.  *  HRESULT         Return value of IOleLink::SetUpdateOptions.
  188.  */
  189.  
  190. STDMETHODIMP CIOleUILinkContainer::SetLinkUpdateOptions(DWORD dwLink
  191.     , DWORD dwOptions)
  192.     {
  193.     LPOLELINK       pIOleLink;
  194.     HRESULT         hr;
  195.  
  196.     if (NULL==dwLink)
  197.         return ResultFromScode(E_FAIL);
  198.  
  199.     /*
  200.      * Your responsibility is to call the object's
  201.      * IOleLink::SetUpdateOptions function with dwOptions.  Simple?
  202.      *
  203.      * For Patron we must first get the object pointer obtainable
  204.      * from the tenant's ObjectGet function, then QI for IOleLink.
  205.      */
  206.  
  207.     GetObjectInterface(dwLink, IID_IOleLink, (LPLPVOID)&pIOleLink);
  208.     hr=pIOleLink->SetUpdateOptions(dwOptions);
  209.     pIOleLink->Release();
  210.  
  211.     m_fDirty=SUCCEEDED(hr);
  212.     return hr;
  213.     }
  214.  
  215.  
  216.  
  217.  
  218.  
  219. /*
  220.  * CIOleUILinkContainer::GetLinkUpdateOptions
  221.  *
  222.  * Purpose:
  223.  *  Requests the container to call IOleLink::GetUpdateOptions for
  224.  *  the object identified by dwLink.
  225.  *
  226.  * Parameters:
  227.  *  dwLink          DWORD identifying the object
  228.  *  pdwOptions      LPDWORD in which to store the options.
  229.  *
  230.  * Return Value:
  231.  *  HRESULT         Return value of IOleLink::GetUpdateOptions
  232.  */
  233.  
  234. STDMETHODIMP CIOleUILinkContainer::GetLinkUpdateOptions(DWORD dwLink
  235.     , LPDWORD pdwOptions)
  236.     {
  237.     LPOLELINK       pIOleLink;
  238.     HRESULT         hr;
  239.  
  240.     if (NULL==dwLink)
  241.         return ResultFromScode(E_FAIL);
  242.  
  243.     GetObjectInterface(dwLink, IID_IOleLink, (LPLPVOID)&pIOleLink);
  244.     hr=pIOleLink->GetUpdateOptions(pdwOptions);
  245.     pIOleLink->Release();
  246.  
  247.     return hr;
  248.     }
  249.  
  250.  
  251.  
  252.  
  253.  
  254. /*
  255.  * CIOleUILinkContainer::SetLinkSource
  256.  *
  257.  * Purpose:
  258.  *  Changes the moniker to which an object is linked.
  259.  *
  260.  * Parameters:
  261.  *  dwLink          DWORD identifying the object in question.
  262.  *  pszName         LPSTR to the displayable name of the source.
  263.  *  cchName         ULONG length of the file portaion of pszName
  264.  *  pchEaten        ULONG FAR * in which to return the number of characters
  265.  *                  used in parsing pszDisplayName.
  266.  *  fValidate       BOOL indicating if we're to validate that the source
  267.  *                  exists first.
  268.  *
  269.  * Return Value:
  270.  *  HRESULT         NOERROR if successful, E_FAIL otherwise.
  271.  */
  272.  
  273. STDMETHODIMP CIOleUILinkContainer::SetLinkSource(DWORD dwLink, LPSTR pszName
  274.     , ULONG cchName, ULONG FAR * pchEaten, BOOL fValidate)
  275.     {
  276.     LPTENANT        pTenant=(LPTENANT)dwLink;
  277.     HRESULT         hr;
  278.     LPOLELINK       pIOleLink;
  279.  
  280.     if (NULL==dwLink)
  281.         return ResultFromScode(E_FAIL);
  282.  
  283.     //This is for use in GetLinkSource, below.
  284.     pTenant->m_fLinkAvail=FALSE;
  285.  
  286.     GetObjectInterface(dwLink, IID_IOleLink, (LPLPVOID)&pIOleLink);
  287.     hr=m_pDelIUILinks->SetLinkSource((DWORD)pIOleLink, pszName
  288.         , cchName, pchEaten, fValidate);
  289.     pIOleLink->Release();
  290.  
  291.     if (FAILED(hr))
  292.         return hr;
  293.  
  294.     //hr will be S_FALSE if link is unavailable.
  295.     pTenant->Repaint();
  296.     pTenant->m_fLinkAvail=(NOERROR==hr);
  297.     m_fDirty=TRUE;
  298.     return NOERROR;
  299.     }
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306. /*
  307.  * CIOleUILinkContainer::GetLinkSource
  308.  *
  309.  * Purpose:
  310.  *  Retrieves various strings and values for this link source.
  311.  *
  312.  * Parameters:
  313.  *  dwLink          DWORD identifying the object affected.
  314.  *  ppszName        LPSTR FAR * in which to return the new source name
  315.  *  pcchName        ULONG FAR * in which to return the length of pszName
  316.  *  ppszFullLink    LPSTR FAR * in which to return the full name of
  317.  *                  the class of linked object.
  318.  *  ppszShortLink   LPSTR FAR * in which to return the short name of
  319.  *                  the class of linked object.
  320.  *  pfSourceAvail   BOOL FAR * in which to return if this is an available
  321.  *                  link source.
  322.  *  pfSelected      BOOL FAR * in which to return if this object is currently
  323.  *                  selected in the document.  This selects the item in the
  324.  *                  listbox for this object.
  325.  *
  326.  * Return Value:
  327.  *  HRESULT         NOERROR on success, error code otherwise.
  328.  */
  329.  
  330. STDMETHODIMP CIOleUILinkContainer::GetLinkSource(DWORD dwLink
  331.     , LPSTR FAR *ppszName, ULONG FAR *pcchName, LPSTR FAR *ppszFullLink
  332.     , LPSTR FAR *ppszShortLink, BOOL FAR *pfSourceAvail, BOOL FAR * pfSelected)
  333.     {
  334.     HRESULT         hr;
  335.     LPTENANT        pTenant=(LPTENANT)dwLink;
  336.     LPOLELINK       pIOleLink=NULL;
  337.     LPOLEOBJECT     pIOleObject=NULL;
  338.     LPMONIKER       pmk=NULL;
  339.     LPMONIKER       pmkFirst=NULL;
  340.     LPBC            pbc=NULL;
  341.  
  342.     if (NULL==dwLink)
  343.         return ResultFromScode(E_FAIL);
  344.  
  345.     //We know what this is from SetLinkSource
  346.     *pfSourceAvail=pTenant->m_fLinkAvail;
  347.  
  348.     if (pfSelected)
  349.         *pfSelected=pTenant->FIsSelected();
  350.  
  351.     hr=GetObjectInterface(dwLink, IID_IOleLink, (LPLPVOID)&pIOleLink);
  352.  
  353.     if (FAILED(hr))
  354.         return hr;
  355.  
  356.     hr=m_pDelIUILinks->GetLinkSource((DWORD)pIOleLink, ppszName, pcchName
  357.         , ppszFullLink, ppszShortLink, pfSourceAvail, pfSelected);
  358.  
  359.     pIOleLink->Release();
  360.     return hr;
  361.     }
  362.  
  363.  
  364.  
  365.  
  366.  
  367. /*
  368.  * CIOleUILinkContainer::OpenLinkSource
  369.  *
  370.  * Purpose:
  371.  *  Asks the container to call DoVerb on this object with OLEIVERB_SHOW.
  372.  *
  373.  * Parameters:
  374.  *  dwLink          DWORD identifying the linked object.
  375.  *
  376.  * Return Value:
  377.  *  HRESULT         Standard.
  378.  */
  379.  
  380. STDMETHODIMP CIOleUILinkContainer::OpenLinkSource(DWORD dwLink)
  381.     {
  382.     LPTENANT        pTenant=(LPTENANT)dwLink;
  383.  
  384.     pTenant->Activate(OLEIVERB_OPEN);
  385.     return NOERROR;
  386.     }
  387.  
  388.  
  389.  
  390.  
  391. /*
  392.  * CIOleUILinkContainer::UpdateLink
  393.  *
  394.  * Purpose:
  395.  *  Asks the container to update the link for this object.
  396.  *
  397.  * Parameters:
  398.  *  dwLink          DWORD identifying the linked object.
  399.  *  fErrorMessage   BOOL indicating if we can show errors.
  400.  *  fErrorAction    BOOL making no sense whatsoever.
  401.  *
  402.  * Return Value:
  403.  *  HRESULT         Standard.
  404.  */
  405.  
  406. STDMETHODIMP CIOleUILinkContainer::UpdateLink(DWORD dwLink
  407.     , BOOL fErrorMessage, BOOL fErrorAction)
  408.     {
  409.     LPTENANT        pTenant=(LPTENANT)dwLink;
  410.     LPOLELINK       pIOleLink;
  411.     HRESULT         hr;
  412.  
  413.     hr=GetObjectInterface(dwLink, IID_IOleLink, (LPLPVOID)&pIOleLink);
  414.  
  415.     if (FAILED(hr))
  416.         return hr;
  417.  
  418.     hr=m_pDelIUILinks->UpdateLink((DWORD)pIOleLink, fErrorMessage, fErrorAction);
  419.  
  420.     pTenant->Repaint();
  421.     pTenant->m_fLinkAvail=SUCCEEDED(hr);
  422.     pIOleLink->Release();
  423.  
  424.     if (FAILED(hr))
  425.         {
  426.         if (fErrorMessage)
  427.             MessageBox(m_pPage->m_hWnd, "Could not update link.", "Patron", MB_OK);
  428.         }
  429.     else
  430.         m_fDirty=TRUE;
  431.  
  432.     return hr;
  433.     }
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440. /*
  441.  * CIOleUILinkContainer::CancelLink
  442.  *
  443.  * Purpose:
  444.  *  Requests that the container turn this linked object into a static
  445.  *  object.
  446.  *
  447.  * Parameters:
  448.  *  dwLink          DWORD identifying the linked object.
  449.  *
  450.  * Return Value:
  451.  *  HRESULT         Standard.
  452.  */
  453.  
  454. STDMETHODIMP CIOleUILinkContainer::CancelLink(DWORD dwLink)
  455.     {
  456.     LPTENANT        pTenant=(LPTENANT)dwLink;
  457.     LPOLELINK       pIOleLink;
  458.     HRESULT         hr;
  459.  
  460.     hr=GetObjectInterface(dwLink, IID_IOleLink, (LPLPVOID)&pIOleLink);
  461.  
  462.     if (FAILED(hr))
  463.         return hr;
  464.  
  465.     //This sets the source moniker to NULL.
  466.     m_pDelIUILinks->CancelLink((DWORD)pIOleLink);
  467.     pIOleLink->Release();
  468.  
  469.     //Go change this object over to a static one.
  470.     pTenant->FConvertToStatic();
  471.  
  472.     m_fDirty=TRUE;
  473.     return NOERROR;
  474.     }
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481. //PROTECTED FUNCTIONS INTERNAL TO CIOleUILinkContainer
  482.  
  483.  
  484. /*
  485.  * CIOleUILinkContainer::GetObjectInterface
  486.  * (Protected)
  487.  *
  488.  * Purpose:
  489.  *  Retrieves and interface pointer for the object identified by dwLink
  490.  *
  491.  * Parameters:
  492.  *  dwLink          DWORD identifying the object
  493.  *  riid            REFIID of the interface desired.
  494.  *  ppv             LPLPVOID into which we return the pointer.
  495.  *
  496.  * Return Value:
  497.  *  HRESULT         NOERROR on success, error code otherwise.
  498.  */
  499.  
  500. STDMETHODIMP CIOleUILinkContainer::GetObjectInterface(DWORD dwLink
  501.     , REFIID riid, LPLPVOID ppv)
  502.     {
  503.     LPTENANT        pTenant=(LPTENANT)dwLink;
  504.     LPUNKNOWN       pIUnknown;
  505.     HRESULT         hr;
  506.  
  507.     pTenant->ObjectGet((LPUNKNOWN FAR *)&pIUnknown);
  508.     hr=pIUnknown->QueryInterface(riid, ppv);
  509.     pIUnknown->Release();
  510.  
  511.     return hr;
  512.     }
  513.